home *** CD-ROM | disk | FTP | other *** search
- Subject: v09i029: A TECO text editor, Part02/04
- Newsgroups: mod.sources
- Approved: rs@mirror.TMC.COM
-
- Submitted by: genrad!mlf
- Mod.sources: Volume 9, Issue 29
- Archive-name: teco/Part02
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line,
- # then unpack it by saving it in a file and typing "sh file".
- # If this archive is complete, you will see the message:
- # "End of archive 2 (of 4)."
- # Contents: te_chario.c te_defs.h te_srch.c te_subs.c
- # Wrapped by rs@mirror on Thu Mar 12 19:54:28 1987
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- echo shar: Extracting \"te_chario.c\" \(9049 characters\)
- if test -f te_chario.c ; then
- echo shar: Will not over-write existing file \"te_chario.c\"
- else
- sed "s/^X//" >te_chario.c <<'END_OF_te_chario.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_chario.c character I/O routines 10/9/86 */
- X#include <errno.h>
- X#include "te_defs.h"
- X
- X#include <fcntl.h>
- X#ifndef DEBUG
- X#include <signal.h>
- Xextern int int_handler();
- Xextern int stp_handler();
- Xextern int hup_handler();
- X#define SIGINTMASK 2
- X#endif
- X
- Xint lf_sw; /* nonzero: make up a LF following an entered CR */
- Xint ttyflags; /* flags for (stdin) file descriptor */
- Xstruct tchars tc_orig, tc_new, tc_noint; /* original, new, disabled intrpt tty special chars */
- Xstruct ltchars lc_orig, lc_new; /* original and new local special chars */
- Xstruct sgttyb tty_orig, tty_new; /* original and new tty flags */
- Xint tty_local; /* original tty local mode flags */
- Xint lnoflsh = LNOFLSH; /* bit to force "no flush on interrupt */
- X
- X#ifndef DEBUG
- Xstruct sigvec intsigstruc = { int_handler, 0, 0 } ; /* info structure for ^C interrupt */
- Xstruct sigvec stpsigstruc = { stp_handler, 0, 0 } ; /* info structure for "stop" signal */
- Xstruct sigvec hupsigstruc = { hup_handler, 0, 0 } ; /* info structure for "hangup" signal */
- Xstruct sigvec nosigstr = { SIG_DFL, 0, 0 }; /* default structure for signal */
- X#endif
- X
- Xint inp_noterm; /* nonzero if standard input is not a terminal */
- Xint out_noterm; /* nonzero if standard output is not a terminal */
- X/* set tty (stdin) mode. TECO mode is CBREAK, no ECHO, sep CR & LF */
- X/* operation; normal mode is none of the above. TTY_OFF and TTY_ON do this */
- X/* absolutely; TTY_SUSP and TTY_RESUME use saved signal status. */
- X
- Xsetup_tty(arg)
- X int arg;
- X {
- X extern int errno;
- X int ioerr;
- X struct sgttyb tmpbuf;
- X
- X/* initial processing: set tty mode */
- X
- X if (arg == TTY_ON)
- X {
- X ioerr = ioctl(fileno(stdin), TIOCGETP, &tty_orig); /* get std input characteristics */
- X inp_noterm = (ioerr && (errno == ENOTTY)); /* nonzero if input not a terminal */
- X ioerr = ioctl(fileno(stdout), TIOCGETP, &tmpbuf); /* get std output characteristics */
- X out_noterm = (ioerr && (errno == ENOTTY)); /* nonzero if output not a terminal */
- X ioctl(fileno(stdout), TIOCLGET, &tty_local); /* get current "local mode flags" word */
- X
- X ttybuf = tty_new = tty_orig; /* make a copy of tty control structure */
- X tty_new.sg_flags = (tty_new.sg_flags & ~ECHO & ~CRMOD) | CBREAK; /* turn on teco modes */
- X
- X ioctl(fileno(stdin), TIOCGETC, &tc_orig); /* read current tchars */
- X tc_new = tc_orig; /* make local copy */
- X tc_new.t_quitc = tc_new.t_brkc = -1; /* disable "quit" and "delimiter" chars */
- X tc_noint = tc_new;
- X tc_noint.t_intrc = -1; /* disable the interrupt char in this one */
- X
- X ioctl(fileno(stdin), TIOCGLTC, &lc_orig); /* read current ltchars */
- X lc_new = lc_orig; /* make local copy */
- X lc_new.t_rprntc = lc_new.t_werasc = lc_new.t_lnextc = -1; /* disable "reprint," "word erase," "lit next" */
- X }
- X
- X if ((arg == TTY_ON) || (arg == TTY_RESUME))
- X {
- X ioctl(fileno(stdin), TIOCSETP, &tty_new); /* set flags for teco */
- X ioctl(fileno(stdin), TIOCSETC, &tc_new); /* update both */
- X ioctl(fileno(stdin), TIOCSLTC, &lc_new);
- X ioctl(fileno(stdout), TIOCLBIS, &lnoflsh); /* disable "interrupt => flush buffers" */
- X#ifndef DEBUG
- X sigvec(SIGTSTP, &stpsigstruc, 0); /* set up to trap "stop" signal */
- X sigvec(SIGINT, &intsigstruc, 0); /* and "interrupt" signal */
- X sigvec(SIGHUP, &hupsigstruc, 0); /* and "hangup" signal */
- X#endif
- X }
- X else
- X {
- X ioctl(fileno(stdin), TIOCSETP, &tty_orig); /* set flags back to original */
- X ioctl(fileno(stdin), TIOCSETC, &tc_orig); /* put both back to orig states */
- X ioctl(fileno(stdin), TIOCSLTC, &lc_orig);
- X ioctl(fileno(stdout), TIOCLSET, &tty_local); /* restore local mode flags to original states */
- X#ifndef DEBUG
- X sigvec(SIGTSTP, &nosigstr, 0); /* restore default signal handling */
- X sigvec(SIGINT, &nosigstr, 0);
- X sigvec(SIGHUP, &nosigstr, 0);
- X#endif
- X }
- X }
- X/* routines to handle keyboard input */
- X
- X/* routine to get a character without waiting, used by ^T when ET & 64 is set */
- X/* if lf_sw is nonzero, return the LF; else use the FNDELAY fcntl to inquire of the input */
- X
- Xint gettty_nowait()
- X {
- X int c;
- X
- X if (lf_sw)
- X {
- X lf_sw = 0;
- X return(LF); /* LF to be sent: return it */
- X }
- X fcntl(fileno(stdin), F_SETFL, ttyflags | FNDELAY); /* set to "no delay" mode */
- X while (!(c = getchar())); /* read character, or -1, skip nulls */
- X fcntl(fileno(stdin), F_SETFL, ttyflags); /* reset to normal mode */
- X if (c == CR) ++lf_sw; /* CR: set switch to make up a LF */
- X return(c);
- X }
- X
- X
- X
- X/* normal routine to get a character */
- X
- Xint in_read = 0; /* flag for "read busy" (used by interrupt handler) */
- X
- Xchar gettty()
- X {
- X int c;
- X
- X if (lf_sw)
- X {
- X lf_sw = 0;
- X return(LF); /* if switch set, make up a line feed */
- X }
- X ++in_read; /* set "read busy" switch */
- X while(!(c = getchar())); /* get character; skip nulls */
- X in_read = 0; /* clear switch */
- X if (c == CR) ++lf_sw; /* CR: set switch to make up a LF */
- X if (c == EOF) ERROR(E_EFI); /* end-of-file from standard input */
- X return( (char) c & 0177); /* and return the 7-bit char */
- X }
- X
- X#ifndef DEBUG
- X
- X/* routine to handle interrupt signal */
- X
- Xint_handler()
- X {
- X
- X if (exitflag <= 0) /* if executing commands */
- X {
- X if (et_val & ET_CTRLC) et_val &= ~ET_CTRLC; /* if "trap ^C" set, clear it and ignore */
- X else exitflag = -2; /* else set flag to stop execution */
- X }
- X if (in_read) /* if interrupt happened in "getchar" pass a ^C to input */
- X {
- X in_read = 0; /* clear "read" switch */
- X ioctl(fileno(stdin), TIOCSETC, &tc_noint); /* disable interrupt char */
- X qio_char(CTL (C)); /* send a ^C to input stream */
- X ioctl(fileno(stdin), TIOCSETC, &tc_new); /* reenable interrupt char */
- X }
- X }
- X#endif
- X/* routine to disable (1), enable (0) ^C interrupt, used to block interrupts during display update */
- X
- Xint old_mask; /* storage for previous signal mask */
- X#define INT_MASK 2
- X
- Xblock_inter(func)
- X int func;
- X {
- X#ifndef DEBUG
- X if (func) old_mask = sigblock(INT_MASK); /* if arg nonzero, block interrupt */
- X else sigsetmask(old_mask); /* otherwise restore old signal mask */
- X#endif
- X }
- X
- X
- X
- X#ifndef DEBUG
- X/* routine to handle "stop" signal (^Y) */
- X
- Xstp_handler()
- X {
- X window(WIN_SUSP); /* restore screen */
- X setup_tty(TTY_SUSP); /* put tty back to normal */
- X sigvec(SIGTSTP, &nosigstr, 0); /* put default action back */
- X sigsetmask(0); /* unblock "suspend" signal */
- X kill(0, SIGTSTP); /* suspend this process */
- X
- X/* ----- process gets suspended here ----- */
- X
- X sigvec(SIGTSTP, &stpsigstruc, 0); /* restore local handling of "stop" signal */
- X setup_tty(TTY_RESUME); /* restore tty */
- X buff_mod = 0; /* set whole screen modified */
- X if (win_data[7]) /* redraw window */
- X {
- X window(WIN_RESUME); /* re-enable window */
- X window(WIN_REDRAW); /* force complete redraw */
- X window(WIN_REFR); /* and refresh */
- X }
- X qio_char('\0'); /* wake up the input
- X if (exitflag) retype_cmdstr('*'); /* if not executing, prompt again and echo command string so far */
- X }
- X#endif
- X
- X
- X
- X/* simulate a character's having been typed on the keyboard */
- X
- Xqio_char(c)
- X char c;
- X {
- X ioctl(fileno(stdin), TIOCSTI, &c); /* send char to input stream */
- X }
- X/* routine to handle "hangup" signal */
- X#ifndef DEBUG
- X
- Xhup_handler()
- X {
- X if (!exitflag) exitflag = -3; /* if executing, set flag to terminate */
- X else
- X {
- X panic(); /* dump buffer and close output files */
- X exit(1);
- X }
- X }
- X#endif
- X
- X
- X
- X/* type a crlf */
- X
- Xcrlf()
- X {
- X type_char(CR);
- X type_char(LF);
- X }
- X
- X
- X
- X/* reset ^O status */
- X
- Xint lflusho = LFLUSHO;
- Xint lfo;
- X
- Xreset_ctlo()
- X {
- X ioctl(fileno(stdin), TIOCLGET, &lfo); /* read flags */
- X if (lfo & LFLUSHO) /* if ^O was set */
- X {
- X ioctl(fileno(stdin), TIOCLBIC, &lflusho); /* reset ^O */
- X crlf(); /* type a crlf */
- X }
- X }
- X/* routine to type one character */
- X
- Xtype_char(c)
- X char c;
- X {
- X
- X if ((char_count >= WN_width) && (c != CR) && !(spec_chars[c] & A_L)) /* spacing char beyond end of line */
- X {
- X if (et_val & ET_TRUNC) return; /* truncate output to line width */
- X else crlf(); /* otherwise do automatic new line (note recursive call to type_char) */
- X }
- X
- X if ((c & 0140) == 0) /* control char? */
- X {
- X switch (c & 0177)
- X {
- X case CR:
- X putchar(c);
- X char_count = 0;
- X break;
- X
- X case LF:
- X putchar(c);
- X/* scroll_dly(); /* filler chars in case VT-100 scrolls */
- X break;
- X
- X case ESC:
- X if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
- X else
- X {
- X putchar('$');
- X char_count++;
- X }
- X break;
- X
- X case TAB:
- X if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
- X else for (type_char(' '); (char_count & tabmask) != 0; type_char(' '));
- X break;
- X
- X default:
- X if ((et_val & ET_IMAGE) && !exitflag) putchar(c);
- X else
- X {
- X putchar('^');
- X putchar(c + 'A'-1);
- X char_count += 2;
- X }
- X break;
- X }
- X }
- X else
- X {
- X putchar(c);
- X char_count++;
- X }
- X }
- X
- END_OF_te_chario.c
- if test 9049 -ne `wc -c <te_chario.c`; then
- echo shar: \"te_chario.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_defs.h\" \(11866 characters\)
- if test -f te_defs.h ; then
- echo shar: Will not over-write existing file \"te_defs.h\"
- else
- sed "s/^X//" >te_defs.h <<'END_OF_te_defs.h'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_defs.h definitions file 1/9/87 */
- X
- X#include <stdio.h>
- X#include <ctype.h>
- X#include <sgtty.h>
- X#include <setjmp.h>
- X
- X#define CTL(x) (('x') & 0x1f) /* for control chars */
- X#define ERROR(e) longjmp(xxx, (e))
- X#define BLOCKSIZE (0x10000 - 8) /* size of memory block to allocate */
- X#define CELLSIZE 256 /* number of characters per cell */
- X#define CSTACKSIZE 64 /* size of command stack */
- X#define MSTACKSIZE 64 /* size of macro stack */
- X#define QSTACKSIZE 64 /* size of q register stack */
- X#define ESTACKSIZE 64 /* size of expression stack */
- X#define TTIBUFSIZE 1024 /* size of type-ahead buffer */
- X#define BUFF_LIMIT 16384 /* text buffer soft limit for ED & 4 */
- X#define NQREGS 36 /* number of Q registers */
- X#define CBUFF 0 /* id for command buffer */
- X#define SERBUF NQREGS+1 /* and search string buffer */
- X#define FILBUF NQREGS+2 /* and file string buffer */
- X#define SYSBUF NQREGS+3 /* and system command buffer */
- X#define TIMBUF NQREGS+4 /* and time/date buffer */
- X#define cbuf qreg[CBUFF] /* shorthand for command-string header */
- X#define sbuf qreg[SERBUF] /* and for search-buffer header */
- X#define fbuf qreg[FILBUF] /* and for file-buffer header */
- X#define sysbuf qreg[SYSBUF] /* and for system command header */
- X#define timbuf qreg[TIMBUF] /* and for time/date header */
- X#define cptr (*msp) /* command string is top of macro stack */
- X#define cmdstr mstack[0] /* for entering command string */
- X#define TAB 011 /* define special chars */
- X#define LF 012
- X#define VT 013
- X#define FF 014
- X#define CR 015
- X#define ESC 033
- X#define DEL 0177
- X
- X/* expression operators */
- X#define OP_START 1
- X#define OP_ADD 2
- X#define OP_SUB 3
- X#define OP_MULT 4
- X#define OP_DIV 5
- X#define OP_AND 6
- X#define OP_OR 7
- X
- X/* macro flags */
- X#define F_ITER 1
- X
- X/* bits in special-character table */
- X#define A_S 1 /* "skipto()" special character */
- X#define A_T 2 /* command with std text argument */
- X#define A_E 4 /* E<char> takes a text argument */
- X#define A_F 8 /* F<char> takes a text argument */
- X#define A_X 16 /* char causes "skipto()" to exit */
- X#define A_Q 32 /* command with q-register argument */
- X#define A_A 64 /* special char in search string */
- X#define A_L 128 /* character is a line separator */
- X
- X/* error codes */
- X#define E_BNI 1
- X#define E_CPQ 2
- X#define E_COF 3
- X#define E_FNF 4
- X#define E_IEC 5
- X#define E_IFC 6
- X#define E_IIA 7
- X#define E_ILL 8
- X#define E_ILN 9
- X#define E_IPA 10
- X#define E_IQC 11
- X#define E_IQN 12
- X#define E_IRA 13
- X#define E_ISA 14
- X#define E_ISS 15
- X#define E_IUC 16
- X#define E_MEM 17
- X#define E_MRP 18
- X#define E_NAB 19
- X#define E_NAC 20
- X#define E_NAE 21
- X#define E_NAP 22
- X#define E_NAQ 23
- X#define E_NAS 24
- X#define E_NAU 25
- X#define E_NFI 26
- X#define E_NFO 27
- X#define E_NYA 28
- X#define E_OFO 29
- X#define E_PDO 30
- X#define E_POP 31
- X#define E_SNI 32
- X#define E_SRH 33
- X#define E_STL 34
- X#define E_UTC 35
- X#define E_UTM 36
- X#define E_XAB 37
- X#define E_YCA 38
- X#define E_IWA 39
- X#define E_NFR 40
- X#define E_INT 41
- X#define E_EFI 42
- X#define E_IAA 43
- X#define E_AMB 44
- X#define E_SYS 45
- X
- X/* define names for window control registers */
- X#define WN_type win_data[0]
- X#define WN_width win_data[1]
- X#define WN_height win_data[2]
- X#define WN_seeall win_data[3]
- X#define WN_mark win_data[4]
- X#define WN_hold win_data[5]
- X#define WN_origin win_data[6]
- X#define WN_scroll win_data[7]
- X
- X/* define display operations */
- X#define WIN_OFF 0 /* disable window */
- X#define WIN_SUSP 1 /* suspend window */
- X#define WIN_INIT 2 /* turn on window */
- X#define WIN_RESUME 3 /* re-enable window */
- X#define WIN_REFR 4 /* refresh window */
- X#define WIN_LINE 5 /* display one line */
- X#define WIN_REDRAW 6 /* force window absolute redraw on next refresh */
- X#define WIN_DISP 7 /* refresh window even if not enabled */
- X
- X/* define scope special functions */
- X#define VT_CLEAR 0 /* clear screen */
- X#define VT_EEOL 1 /* erase to eol */
- X#define VT_SETSPEC1 2 /* set special (reverse) video */
- X#define VT_SETSPEC2 3 /* alternative special video */
- X#define VT_CLRSPEC 4 /* clear it */
- X#define VT_BS1 5 /* backspace and erase 1 */
- X#define VT_BS2 6 /* backspace and erase 2 */
- X#define VT_LINEUP 7 /* up one line */
- X#define VT_EBOL 8 /* erase from bol */
- X
- X/* define keyboard modes */
- X#define TTY_OFF 0 /* final "off" */
- X#define TTY_SUSP 1 /* temporary suspend */
- X#define TTY_ON 2 /* initial "on" */
- X#define TTY_RESUME 3 /* resume after suspend */
- X
- X/* define values for ED, ET, EZ flags */
- X#define ED_CARET 1
- X#define ED_YPROT 2
- X#define ED_EXPMEM 4
- X#define ED_SFAIL 16
- X#define ED_SMULT 64
- X
- X#define ET_IMAGE 1
- X#define ET_NOECHO 8
- X#define ET_CTRLO 16
- X#define ET_NOWAIT 32
- X#define ET_QUIT 128
- X#define ET_TRUNC 256
- X#define ET_CTRLC 32768
- X
- X#define EZ_CRLF 1
- X#define EZ_READFF 2
- X#define EZ_TAB4 4
- X#define EZ_NOTMPFIL 8
- X#define EZ_NOTABI 16
- X#define EZ_NOVTFF 32
- X#define EZ_MULT 64
- X/* define buffer cell */
- X/* a buffer cell is a forward pointer, a backward pointer, */
- X/* and CELLSIZE characters */
- X
- Xstruct buffcell
- X {
- X struct buffcell *f; /* forward pointer */
- X struct buffcell *b; /* backward pointer */
- X char ch[CELLSIZE]; /* char storage */
- X };
- X
- X/* define structures for buffer header, q-register header, */
- X/* q-register pointer, macro stack entry, and macro iteration list */
- X/* these are really alternative ways of looking at the same cell */
- X
- Xstruct qh /* q-register header */
- X {
- X struct buffcell *f; /* forward pointer */
- X struct buffcell *b; /* backward pointer */
- X int z; /* number of characters */
- X int v; /* q-register numeric value */
- X } ;
- X
- Xstruct qp /* q-register pointer/macro stack entry */
- X {
- X struct qp *f; /* forward pointer */
- X struct buffcell *p; /* pointer to a buffer cell */
- X int c; /* character offset */
- X int z; /* number of characters in object pointed to */
- X int dot; /* current character position */
- X int flag; /* flags for "iteration in process," "ei macro," etc. */
- X struct is *il; /* iteration list pointer */
- X int *condsp; /* saved conditional stack pointer */
- X } ;
- X
- Xstruct is /* macro iteration list entry */
- X {
- X struct is *f; /* forward pointer */
- X struct is *b; /* backward pointer */
- X struct buffcell *p; /* cell with start of iteration */
- X int c; /* char offset where iteration started */
- X int dot; /* char position where iteration started */
- X int count; /* iteration count */
- X int dflag; /* definite iteration flag */
- X } ;
- X
- Xstruct ms /* macro stack entry */ /* not used at present */
- X {
- X struct ms *f; /* forward pointer */
- X struct ms *b; /* backward pointer */
- X struct buffcell *p; /* pointer to a buffer cell */
- X int c; /* character offset */
- X struct is *il; /* pointer to iteration list */
- X } ;
- X
- Xstruct bh /* buffer header list entry */
- X {
- X struct buffcell *f; /* pointer to buffer */
- X struct buffcell *b; /* null pointer */
- X int z; /* number of characters */
- X int v; /* not used */
- X struct bh *ff; /* forward pointer */
- X struct bh *bb; /* backward pointer */
- X } ;
- X
- X/* define expression stack entry */
- Xstruct exp_entry
- X {
- X int val1; /* first value */
- X int flag1; /* nonzero if there is a first value */
- X int val2; /* second value (set by 'comma') */
- X int flag2; /* nonzero if there is one */
- X int exp; /* expression in process */
- X int op; /* operation to be applied */
- X } ;
- X
- X/* define file data structures */
- Xstruct infiledata /* structure of input file info */
- X {
- X FILE *fd; /* file pointer */
- X int eofsw; /* end-of-file switch */
- X } ;
- X
- Xstruct outfiledata /* structure of output file info */
- X {
- X FILE *fd; /* file pointer */
- X char f_name[CELLSIZE+5]; /* real name of output */
- X char t_name[CELLSIZE+5]; /* temporary output name */
- X int name_size; /* number of chars in name */
- X int bak; /* backup flag */
- X } ;
- X
- Xextern struct infiledata *infile; /* pointer to currently active intput file structure */
- Xextern struct outfiledata *outfile; /* pointer to currently active output file structure */
- Xextern struct outfiledata po_file, so_file; /* output file descriptors */
- X/* define global variables, etc. */
- X
- Xextern int char_count; /* char count for tab typer */
- Xextern char lastc; /* last char read */
- Xextern int ttyerr; /* error return from ioctl */
- Xextern int errno; /* system error code */
- Xextern struct sgttyb ttybuf; /* local copy of tty control data */
- Xextern int inp_noterm; /* nonzero if standard in is not a terminal */
- Xextern int out_noterm; /* nonzero if standard out is not a term. */
- Xextern jmp_buf xxx; /* preserved environment for error restart */
- Xextern int err; /* local error code */
- Xextern struct qp t_qp; /* temporary buffer pointer */
- Xextern struct qp aa, bb, cc; /* more temporaries */
- Xextern struct buffcell t_bcell; /* temporary bcell */
- Xextern int tabmask; /* mask for selecting 4/8 char tabs */
- Xextern int exitflag; /* flag for ending command str exec */
- Xextern char term_char; /* terminator for insert, search, etc. */
- Xextern char cmdc; /* current command character */
- Xextern char skipc; /* char found by "skipto()" */
- Xextern int dot, z, tdot; /* current, last, temp buffer position */
- Xextern int ll, mm, nn; /* general temps */
- Xextern int ins_count; /* count of chars inserted */
- Xextern int ctrl_e; /* form feed flag */
- Xextern int ctrl_r; /* current number radix (8, 10, 16) */
- Xextern int ctrl_s; /* string length for S, I, G */
- Xextern int ctrl_x; /* search case flag */
- Xextern int ed_val; /* ED value */
- Xextern int es_val; /* ES value */
- Xextern int et_val; /* ET value */
- Xextern int eu_val; /* EU value */
- Xextern int ev_val; /* EV value */
- Xextern int ez_val; /* EZ value */
- Xextern int srch_result; /* result of last :S executed */
- Xextern int atflag; /* flag for @ char typed */
- Xextern int colonflag; /* flag for : char typed */
- Xextern int trace_sw; /* nonzero if tracing command exec */
- X
- Xextern int win_data[]; /* window control parameters */
- Xextern struct buffcell *insert_p; /* pointer to temp text buffer during insert */
- Xextern int buff_mod; /* set to earliest buffer change */
- Xextern int search_flag; /* set nonzero by search */
- X
- Xextern char *errors[]; /* error text */
- Xextern char mapch[], mapch_l[]; /* char mapping tables */
- Xextern char spec_chars[]; /* special character table */
- X
- Xextern char skipto(), find_endcond(), getcmdc(), getcmdc0(); /* routines that return chars */
- X
- Xextern FILE *eisw; /* indirect command file pointer */
- Xextern FILE *fopen();
- X
- Xextern struct buffcell *freebuff; /* buffcell free-list pointer */
- Xextern struct buffcell *dly_freebuff; /* delayed free-list pointer */
- Xextern struct qp *freedcell; /* cell free-list pointer */
- Xextern struct buffcell *get_bcell(); /* get buffcell routine */
- Xextern struct qp *get_dcell(); /* get data cell routine */
- X
- X/* the text buffer header */
- Xextern struct qh buff;
- X
- X/* the q-register headers point to the start of the buffer and registers */
- Xextern struct qh qreg[]; /* for q regs, command, search, file */
- X
- X/* the q-register stack contains temporary copies of q-register contents */
- Xextern struct qh qstack[]; /* q-reg stack */
- Xextern struct qh *qsp; /* q-reg stack pointer */
- X
- X/* the macro stack contains pointers to the currently active macros. */
- X/* the top of the stack is the command pointer */
- Xextern struct qp mstack[]; /* macro stack */
- Xextern struct qp *msp; /* macro stack pointer */
- X
- X/* the expression stack */
- Xextern struct exp_entry estack[]; /* expression stack */
- Xextern struct exp_entry *esp; /* expression stack pointer */
- X
- END_OF_te_defs.h
- if test 11866 -ne `wc -c <te_defs.h`; then
- echo shar: \"te_defs.h\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_srch.c\" \(14562 characters\)
- if test -f te_srch.c ; then
- echo shar: Will not over-write existing file \"te_srch.c\"
- else
- sed "s/^X//" >te_srch.c <<'END_OF_te_srch.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_srch.c routines associated with search operations 2/5/86 */
- X#include "te_defs.h"
- X
- X/* routine to read in a string with string-build characters */
- X/* used for search, tag, file name operations */
- X/* returns 0 if empty string entered, nonzero otherwise */
- X
- Xint build_string(buff)
- X struct qh *buff; /* arg is addr of q-reg header */
- X {
- X int count; /* char count */
- X struct buffcell *tp; /* pointer to temporary string */
- X char c; /* temp character */
- X
- X term_char = (atflag) ? getcmdc(trace_sw) : ESC; /* read terminator */
- X count = atflag = 0; /* initialize char count */
- X if (!peekcmdc(term_char)) /* if string is not empty */
- X {
- X
- X/* create a temporary string and read chars into it until the terminator */
- X for (tp = bb.p = get_bcell(), bb.c = 0; (c = getcmdc(trace_sw)) != term_char; )
- X {
- X if ((c == '^') && !(ed_val & ED_CARET)) /* read next char as CTL */
- X {
- X if ((c = getcmdc(trace_sw)) == term_char) ERROR(msp <= &mstack[0] ? E_UTC : E_UTM);
- X c &= 0x1f;
- X }
- X if ((c &= 0177) < ' ') /* if a control char */
- X {
- X switch (c)
- X {
- X case CTL (Q): /* take next char literally */
- X case CTL (R):
- X if ((c = getcmdc(trace_sw)) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X break; /* fetch character and go store */
- X
- X case CTL (V): /* take next char as lower case */
- X if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X c = mapch_l[cmdc];
- X break;
- X
- X case CTL (W): /* take next char as upper case */
- X if ((c = getcmdc(trace_sw)) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X if (islower(c)) c = toupper(c);
- X break;
- X
- X case CTL (E): /* expanded constructs */
- X if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X switch (mapch_l[cmdc])
- X {
- X case 'u': /* use char in q-reg */
- X if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X c = qreg[getqspec(1, cmdc)].v & 0x7f;
- X break;
- X
- X case 'q': /* use string in q-reg */
- X if (getcmdc(trace_sw) == term_char) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X ll = getqspec(1, cmdc); /* read the reg spec */
- X aa.p = qreg[ll].f; /* set a pointer to it */
- X aa.c = 0;
- X for (mm = 0; mm < qreg[ll].z; mm++)
- X {
- X bb.p->ch[bb.c] = aa.p->ch[aa.c]; /* store char */
- X fwdcx(&bb); /* store next char */
- X fwdc(&aa);
- X ++count;
- X }
- X continue; /* repeat loop without storing */
- X
- X default:
- X bb.p->ch[bb.c] = CTL (E); /* not special: store the ^E */
- X fwdcx(&bb);
- X ++count;
- X c = cmdc; /* and go store the following char */
- X break;
- X
- X } /* end ^E switch */
- X } /* end outer switch */
- X } /* end "if a control char */
- X bb.p->ch[bb.c] = c; /* store character */
- X fwdcx(&bb); /* advance pointer */
- X ++count; /* count characters */
- X } /* end "for" loop */
- X free_blist(buff->f); /* return old buffer */
- X buff->f = tp; /* put in new one */
- X buff->f->b = (struct buffcell *) buff;
- X buff->z = count; /* store count of chars in string */
- X } /* end non-null string */
- X else getcmdc(trace_sw); /* empty string: consume terminator */
- X return(count); /* return char count */
- X }
- X
- X
- X
- X
- X/* routine to handle end of a search operation */
- X/* called with pass/fail result from search */
- X/* returns same pass/fail result */
- X
- Xint end_search(result)
- X int result;
- X {
- X if (!result) /* if search failed */
- X {
- X if (!(esp->flag2 || (ed_val & ED_SFAIL))) dot = 0; /* if an unbounded search failed, clear ptr */
- X if (!colonflag && !peekcmdc(';')) ERROR(E_SRH); /* if no real or implied colon, error if failure */
- X }
- X esp->flag1 = colonflag; /* return a value if a :S command */
- X srch_result = esp->val1 = result; /* and leave it for next ";" */
- X esp->flag2 = colonflag = atflag = 0; /* consume arguments */
- X esp->op = OP_START;
- X return(result);
- X }
- X
- X/* routine to set up for search operation */
- X/* reads search arguments, returns search count */
- X
- Xstatic struct qp sm, sb; /* match-string and buffer pointers */
- Xstatic char *pmap; /* pointer to character mapping table */
- Xstatic int locb; /* reverse search limit */
- Xstatic int last_z; /* end point for reverse search */
- X
- Xint setup_search()
- X {
- X int count; /* string occurrence counter */
- X
- X set_pointer(dot, &aa); /* set a pointer to start of search */
- X if (colonflag >= 2) esp->flag2 = esp->flag1 = esp->val2 = esp->val1 = 1; /* ::S is 1,1S */
- X if ((count = get_value(1)) == 0) ERROR(E_ISA); /* read search count: default is 1 */
- X else if (count > 0) /* search forward */
- X {
- X if (esp->flag2) /* if bounded search */
- X {
- X if (esp->val2 < 0) esp->val2 = -(esp->val2); /* set limit */
- X if ((aa.z = dot + esp->val2) > z) aa.z = z; /* or z, whichever less */
- X }
- X else aa.z = z;
- X }
- X else
- X {
- X if (esp->flag2) /* if bounded search */
- X {
- X if (esp->val2 < 0) esp->val2 = -(esp->val2); /* set limit */
- X if ((locb = dot - esp->val2) < 0) locb = 0; /* or 0, whichever greater */
- X }
- X else locb = 0;
- X }
- X return(count);
- X }
- X
- X/* routine to do N, _, E_ searches: search, if search fails, then get */
- X/* next page and continue */
- X
- Xdo_nsearch(arg)
- X char arg; /* arg is 'n', '_', or 'e' to define which search */
- X {
- X int scount; /* search count */
- X
- X build_string(&sbuf); /* read the search string */
- X if ((scount = get_value(1)) <= 0) ERROR(E_ISA); /* count must be >0 */
- X set_pointer(dot, &aa); /* start search at dot */
- X esp->flag2 = locb = 0; /* make it unbounded */
- X
- X while (scount > 0) /* search until found */
- X {
- X if (!do_search(1)) /* search forwards */
- X { /* if search fails... */
- X if (infile->eofsw || !infile->fd) break; /* if no input, quit */
- X if (arg == 'n')
- X {
- X set_pointer(0, &aa); /* write file if 'n' */
- X write_file(&aa, z, ctrl_e);
- X }
- X
- X /* not 'n': if _, and an output file, and data to lose, error */
- X else if ((arg == '_') && (outfile->fd) && (z) && (ed_val & ED_YPROT)) ERROR(E_YCA);
- X
- X buff_mod = dot = z = 0; /* clear buffer */
- X set_pointer(0, &aa);
- X read_file(&aa, &z, (ed_val & ED_EXPMEM ? -1 : 0) ); /* read next page */
- X set_pointer(0, &aa); /* search next page from beginning */
- X }
- X else --scount; /* search successful: one fewer to look for */
- X }
- X return( end_search( (scount == 0) ? -1 : 0) ); /* use end_search to clean up */
- X }
- X
- X
- X/* routine to do "FB" search - m,nFB is search from m to n, */
- X/* nFB is search from . to nth line */
- X/* convert arguments to args of normal m,nS command */
- X
- Xint do_fb() /* returns search result */
- X {
- X if (esp->flag1 && esp->flag2) /* if two arguments */
- X {
- X dot = esp->val2; /* start from "m" arg */
- X esp->val2 = esp->val1 - esp->val2; /* get number of chars */
- X }
- X else /* if no or one args, treat as number of lines */
- X {
- X esp->val2 = lines(get_value(1)); /* number of chars */
- X esp->flag2 = esp->flag1 = 1; /* conjure up two args */
- X }
- X esp->val1 = (esp->val2 > 0) ? 1 : -1; /* set search direction */
- X
- X build_string(&sbuf); /* read search string and terminator */
- X return(end_search( do_search( setup_search() ) )); /* do search and return result */
- X }
- X
- X/* routine to do search operation: called with search count as argument */
- X/* returns -1 (pass) or 0 (fail) */
- X
- Xint do_search(count)
- X int count;
- X {
- X pmap = (ctrl_x) ? &mapch[0] : &mapch_l[0]; /* set approp. mapping table */
- X sm.z = sbuf.z; /* copy # of chars in search buffer */
- X
- X if (count > 0)
- X {
- X for (sm.dot = 0; count > 0; count--) /* loop to count occurrences */
- X {
- X for (; aa.dot < aa.z; aa.dot++) /* loop to advance search pointer */
- X {
- X for (sb.p = aa.p, sb.c = aa.c, sb.dot = aa.dot, sm.p = sbuf.f, sm.dot = sm.c = 0;
- X (sb.dot < z) && (sm.dot < sm.z); sm.dot++, sb.dot++)
- X { /* for each char in search string */
- X if (spec_chars[ sm.p->ch[sm.c] ] & A_A) /* if search string char is "special" */
- X {
- X if (!srch_cmp()) break; /* then use expanded comparison routine */
- X }
- X else if (*(pmap + sb.p->ch[sb.c]) != *(pmap + sm.p->ch[sm.c])) break; /* else just compare */
- X if (++sm.c > CELLSIZE-1) /* advance search-string ptr */
- X {
- X sm.p = sm.p->f;
- X sm.c = 0;
- X }
- X if (++sb.c > CELLSIZE-1) /* advance buffer ptr */
- X {
- X sb.p = sb.p->f;
- X sb.c = 0;
- X }
- X } /* end comparison loop */
- X
- X if (sm.dot >= sm.z) break; /* exit if found */
- X if (++aa.c > CELLSIZE-1) /* else not found: advance buffer pointer */
- X {
- X aa.p = aa.p->f;
- X aa.c = 0;
- X }
- X } /* end search loop */
- X
- X if (sm.dot < sm.z) break; /* if one search failed, don't do more */
- X else
- X {
- X ctrl_s = aa.dot - sb.dot; /* otherwise save -length of string found */
- X if ((ed_val & ED_SMULT) && (count > 1)) /* if funny "advance by 1" mode */
- X {
- X ++aa.dot; /* advance buffer pointer by one only */
- X if (++aa.c > CELLSIZE-1)
- X {
- X aa.p = aa.p->f;
- X aa.c = 0;
- X }
- X }
- X else
- X {
- X aa.dot = sb.dot; /* advance search pointer past string */
- X aa.p = sb.p;
- X aa.c = sb.c;
- X }
- X }
- X } /* end "search n times" */
- X } /* end "search forwards" */
- X
- X else /* search backwards */
- X {
- X for (last_z = z, sm.dot = 0; count < 0; count++) /* loop to count occurrences */
- X {
- X for (; aa.dot >= locb; aa.dot--) /* loop to advance (backwards) search pointer */
- X {
- X for (sb.p = aa.p, sb.c = aa.c, sb.dot = aa.dot, sm.p = sbuf.f, sm.dot = sm.c = 0;
- X (sb.dot < last_z) && (sm.dot < sm.z); sm.dot++, sb.dot++)
- X { /* loop to compare string */
- X if (spec_chars[ sm.p->ch[sm.c] ] & A_A) /* if search string char is "special" */
- X {
- X if (!srch_cmp()) break; /* then use expanded comparison routine */
- X }
- X else if (*(pmap + sb.p->ch[sb.c]) != *(pmap + sm.p->ch[sm.c])) break; /* else just compare */
- X if (++sm.c > CELLSIZE-1) /* advance search-string ptr */
- X {
- X sm.p = sm.p->f;
- X sm.c = 0;
- X }
- X if (++sb.c > CELLSIZE-1) /* advance buffer ptr */
- X {
- X sb.p = sb.p->f;
- X sb.c = 0;
- X }
- X } /* end comparison loop */
- X if (sm.dot >= sm.z) /* search matches: */
- X {
- X if (!(ed_val & ED_SMULT)) last_z = aa.dot; /* set last_z to point where this string was found */
- X break;
- X }
- X if (sb.dot >= last_z) /* or if string is beyond end of buffer */
- X {
- X sm.dot = sm.z; /* make search appear to have succeeded */
- X --count; /* so as to back up pointer, and force one more look */
- X break;
- X }
- X if (--aa.c < 0) /* else advance buffer pointer (backwards) */
- X {
- X aa.p = aa.p->b;
- X aa.c = CELLSIZE-1;
- X }
- X } /* end search loop */
- X if (sm.dot < sm.z) break; /* if one search failed, don't do more */
- X else
- X {
- X if (count < -1) backc(&aa); /* if this is not last search, back pointer up one */
- X else
- X {
- X ctrl_s = aa.dot - sb.dot; /* otherwise save -length of string found */
- X aa.dot = sb.dot; /* advance pointer past string */
- X aa.p = sb.p;
- X aa.c = sb.c;
- X }
- X }
- X } /* end "search n times" */
- X } /* end "search backwards" */
- X if (sm.dot >= sm.z) dot = aa.dot; /* if search succeeded, update pointer */
- X search_flag = 1; /* set "search occurred" (for ES) */
- X return((sm.dot >= sm.z) ? -1 : 0); /* and return -1 (pass) or 0 (fail) */
- X } /* end "do_search" */
- X
- X/* expanded search comparison */
- X/* returns 1 if match, 0 if not */
- X
- Xint srch_cmp()
- X {
- X int tq; /* q-reg name for ^EGq */
- X struct qp tqp; /* pointer to read q reg */
- X
- X switch (mapch_l[sm.p->ch[sm.c]]) /* what is search character */
- X {
- X case CTL (N): /* match anything but following construct */
- X if (sm.dot >= sm.z) ERROR(E_ISS); /* don't read past end of string */
- X fwdc(&sm); /* skip the ^N */
- X return(!srch_cmp());
- X
- X case CTL (X): /* match any character */
- X return(1);
- X
- X case CTL (Q): /* take next char literally */
- X case CTL (R):
- X if (sm.dot >= sm.z) ERROR(E_ISS); /* don't read past end of string */
- X fwdc(&sm); /* skip the ^Q */
- X return(*(pmap + sb.p->ch[sb.c]) == *(pmap + sm.p->ch[sm.c]));
- X
- X case CTL (S): /* match any nonalphanumeric */
- X return(!isalnum(sb.p->ch[sb.c]));
- X
- X case CTL (E):
- X if (sm.dot >= sm.z) ERROR(E_ISS); /* don't read past end of string */
- X fwdc(&sm); /* skip the ^E */
- X switch (mapch_l[sm.p->ch[sm.c]])
- X {
- X case 'a': /* match any alpha */
- X return(isalpha(sb.p->ch[sb.c]));
- X
- X case 'b': /* match any nonalpha */
- X return(!isalnum(sb.p->ch[sb.c]));
- X
- X case 'c': /* rad50 symbol constituent */
- X return(!isalnum(sb.p->ch[sb.c]) || (sb.p->ch[sb.c] == '$') || (sb.p->ch[sb.c] == '.'));
- X
- X case 'd': /* digit */
- X return(isdigit(sb.p->ch[sb.c]));
- X
- X case 'l': /* line terminator LF, VT, FF */
- X return((sb.p->ch[sb.c] == LF) || (sb.p->ch[sb.c] == FF) || (sb.p->ch[sb.c] == VT));
- X
- X case 'r': /* alphanumeric */
- X return(isalnum(sb.p->ch[sb.c]));
- X
- X case 'v': /* lower case */
- X return(islower(sb.p->ch[sb.c]));
- X
- X case 'w': /* upper case */
- X return(isupper(sb.p->ch[sb.c]));
- X
- X case 's': /* any non-null string of spaces or tabs */
- X if (((sb.p->ch[sb.c]&0177) != ' ') && ((sb.p->ch[sb.c]&0177) != TAB)) return(0); /* failure */
- X /* skip remaining spaces or tabs */
- X for ( fwdc(&sb); ((sb.p->ch[sb.c]&0177) == ' ') || ((sb.p->ch[sb.c]&0177) == TAB); fwdc(&sb) );
- X backc(&sb); /* back up one char (calling routine will skip it) */
- X return(1); /* success */
- X
- X case 'g': /* any char in specified q register */
- X if (sm.dot >= sm.z) ERROR(E_ISS); /* don't read past end of string */
- X fwdc(&sm); /* get to the next char */
- X tq = getqspec(1, sm.p->ch[sm.c]); /* read q-reg spec */
- X for (tqp.dot = tqp.c = 0, tqp.p = qreg[tq].f; tqp.dot < qreg[tq].z; fwdc(&tqp))
- X if (*(pmap + tqp.p->ch[tqp.c]) == *(pmap + sb.p->ch[sb.c])) return(1); /* match */
- X return(0); /* fail */
- X
- X default:
- X ERROR(E_ISS);
- X } /* end ^E constructions */
- X
- X default:
- X return(*(pmap + sb.p->ch[sb.c]) == *(pmap + sm.p->ch[sm.c]));
- X } /* end other constructions */
- X }
- X
- END_OF_te_srch.c
- if test 14562 -ne `wc -c <te_srch.c`; then
- echo shar: \"te_srch.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: Extracting \"te_subs.c\" \(13995 characters\)
- if test -f te_subs.c ; then
- echo shar: Will not over-write existing file \"te_subs.c\"
- else
- sed "s/^X//" >te_subs.c <<'END_OF_te_subs.c'
- X/* TECO for Ultrix Copyright 1986 Matt Fichtenbaum */
- X/* This program and its components belong to GenRad Inc, Concord MA 01742 */
- X/* They may be copied if this copyright notice is included */
- X
- X/* te_subs.c subroutines 11/8/85 */
- X#include "te_defs.h"
- X
- X/* routines to copy a string of characters */
- X/* movenchars(from, to, n) */
- X/* from, to are the addresses of qps */
- X/* n is the number of characters to move */
- X/* moveuntil(from, to, c, &n, max) */
- X/* c is the match character that ends the move */
- X/* n is the returned number of chars moved */
- X/* max is the maximum number of chars to move */
- X
- Xmovenchars(from, to, n)
- X struct qp *from, *to; /* address of buffer pointers */
- X register int n; /* number of characters */
- X {
- X register struct buffcell *fp, *tp; /* local qp ".p" pointers */
- X register int fc, tc; /* local qp ".c" subscripts */
- X
- X if (n != 0)
- X {
- X fp = from->p; /* copy pointers to local registers */
- X fc = from->c;
- X tp = to->p;
- X tc = to->c;
- X
- X for (; n > 0; n--)
- X {
- X tp->ch[tc++] = fp->ch[fc++]; /* move one char */
- X
- X if (tc > CELLSIZE-1) /* check current cell done */
- X {
- X if (!tp->f) /* is there another following? */
- X {
- X tp->f = get_bcell(); /* no, add one */
- X tp->f->b = tp;
- X }
- X tp = tp->f;
- X tc = 0;
- X }
- X
- X if (fc > CELLSIZE-1) /* check current cell done */
- X {
- X if (!fp->f) /* oops, run out of source */
- X {
- X if (n > 1) ERROR(E_UTC); /* error if not done */
- X }
- X else {
- X fp = fp->f; /* chain to next cell */
- X fc = 0;
- X }
- X }
- X }
- X from->p = fp; /* restore arguments */
- X to->p = tp;
- X from->c = fc;
- X to->c = tc;
- X }
- X }
- Xmoveuntil(from, to, c, n, max, trace)
- X struct qp *from, *to; /* address of buffer pointers */
- X register char c; /* match char that ends move */
- X int *n; /* pointer to returned value */
- X int max; /* limit on chars to move */
- X int trace; /* echo characters if nonzero */
- X {
- X register struct buffcell *fp, *tp; /* local qpr ".p" pointers */
- X register int fc, tc; /* local qpr ".c" subscripts */
- X
- X fp = from->p; /* copy pointers to local registers */
- X fc = from->c;
- X tp = to->p;
- X tc = to->c;
- X
- X for (*n = 0; fp->ch[fc] != c; (*n)++) /* until terminating char... */
- X {
- X if (max-- <= 0) ERROR((msp <= &mstack[0]) ? E_UTC : E_UTM);
- X tp->ch[tc++] = fp->ch[fc++]; /* move one char */
- X if (trace) type_char(tp->ch[tc-1]); /* type it out if trace mode */
- X
- X if (tc > CELLSIZE-1) /* check current cell done */
- X {
- X if (!tp->f) /* is there another following? */
- X {
- X tp->f = get_bcell(); /* no, add one */
- X tp->f->b = tp;
- X }
- X tp = tp->f;
- X tc = 0;
- X }
- X
- X if (fc > CELLSIZE-1) /* check current cell done */
- X {
- X if (!fp->f) ERROR(E_UTC); /* oops, run out of source */
- X else {
- X fp = fp->f; /* chain to next cell */
- X fc = 0;
- X }
- X }
- X }
- X
- X from->p = fp; /* restore arguments */
- X to->p = tp;
- X from->c = fc;
- X to->c = tc;
- X }
- X
- X/* routine to get numeric argument */
- Xint get_value(d) /* get a value, default is argument */
- X int d;
- X {
- X int v;
- X
- X v = (esp->flag1) ? esp->val1 :
- X (esp->op == OP_SUB) ? -d : d;
- X esp->flag1 = 0; /* consume argument */
- X esp->op = OP_START;
- X return(v);
- X }
- X
- X
- X
- X
- X/* routine to convert a line count */
- X/* returns number of chars between dot and nth line feed */
- X
- Xint lines(arg)
- X register int arg;
- X {
- X register int i, c;
- X register struct buffcell *p;
- X
- X for (i = dot / CELLSIZE, p = buff.f; (i > 0) && (p->f); i--) p = p->f; /* find dot */
- X c = dot % CELLSIZE;
- X if (arg <= 0) /* scan backwards */
- X {
- X for (i = dot; (arg < 1) && (i > 0); ) /* repeat for each line */
- X {
- X --i; /* count characters */
- X if (--c < 0) /* back up the pointer */
- X {
- X if (!(p = p->b)) break;
- X c = CELLSIZE - 1;
- X }
- X if ( (ez_val & EZ_NOVTFF) ? (p->ch[c] == LF) : (spec_chars[p->ch[c]] & A_L) ) ++arg; /* if line sep found */
- X }
- X if (arg > 0) ++i; /* if terminated on a line separator, advance over the separator */
- X }
- X
- X else /* scan forwards */
- X {
- X for (i = dot; (arg > 0) && (i < z); i++)
- X {
- X if ( (ez_val & EZ_NOVTFF) ? (p->ch[c] == LF) : (spec_chars[p->ch[c]] & A_L) ) --arg;
- X if (++c > CELLSIZE-1)
- X {
- X if (!(p = p->f)) break;
- X c = 0;
- X }
- X } /* this will incr over the separator anyway */
- X }
- X return(i - dot);
- X }
- X
- X/* routine to handle args for K, T, X, etc. */
- X/* if two args, 'char x' to 'char y' */
- X/* if just one arg, then n lines (default 1) */
- X/* sets a pointer to the beginning of the specd */
- X/* string, and a char count value */
- X
- Xint line_args(d, p)
- X int d; /* nonzero: leave dot at start */
- X struct qp *p;
- X {
- X int n;
- X
- X if (esp->flag1 && esp->flag2) /* if two args */
- X {
- X if (esp->val1 <= esp->val2) /* in right order */
- X {
- X if (esp->val1 < 0) esp->val1 = 0;
- X if (esp->val2 > z) esp->val2 = z;
- X if (d) dot = esp->val1; /* update dot */
- X set_pointer(esp->val1, p); /* set the pointer */
- X esp->flag2 = esp->flag1 = 0; /* consume arguments */
- X esp->op = OP_START;
- X return(esp->val2 - esp->val1); /* and return the count */
- X }
- X else
- X {
- X if (esp->val2 < 0) esp->val2 = 0;
- X if (esp->val1 > z) esp->val1 = z;
- X if (d) dot = esp->val2; /* update dot */
- X set_pointer(esp->val2, p); /* args in reverse order */
- X esp->flag2 = esp->flag1 = 0; /* consume arguments */
- X esp->op = OP_START;
- X return(esp->val1 - esp->val2);
- X }
- X }
- X else
- X {
- X n = lines(get_value(1));
- X if (n < -dot) n = -dot;
- X else if (n > z-dot) n = z-dot;
- X if (n >= 0) set_pointer(dot, p);
- X else
- X {
- X n = -n;
- X set_pointer(dot - n, p);
- X if (d) dot -= n;
- X }
- X return(n);
- X }
- X }
- X
- X/* convert character c to a q-register spec */
- Xint getqspec(fors, c) /* fors ("file or search") nonzero = allow _ or * */
- X int fors;
- X char c;
- X {
- X if (isdigit(c)) return(c - '0' + 1);
- X else if isalpha(c) return(mapch_l[c] - 'a' + 11);
- X else if (fors)
- X {
- X if (c == '_') return (SERBUF);
- X if (c == '*') return (FILBUF);
- X if (c == '%') return (SYSBUF);
- X if (c == '#') return (TIMBUF);
- X }
- X ERROR(E_IQN);
- X }
- X
- X
- X
- X/* routines to do insert operations */
- X/* insert1() copies current cell up to dot into a new cell */
- X/* leaves bb pointing to end of that text */
- X/* insert2() copies rest of buffer */
- X
- Xstruct buffcell *insert_p;
- X
- Xinsert1()
- X {
- X int nchars; /* number of chars in cell */
- X
- X set_pointer(dot, &aa); /* convert dot to a qp */
- X if (dot < buff_mod) buff_mod = dot; /* update earliest char loc touched */
- X insert_p = bb.p = get_bcell(); /* get a new cell */
- X bb.c = 0;
- X nchars = aa.c; /* save char position of dot in cell */
- X aa.c = 0;
- X
- X/* now aa points to the beginning of the buffer cell that */
- X/* contains dot, bb points to the beginning of a new cell,*/
- X/* nchars is the number of chars before dot */
- X
- X movenchars(&aa, &bb, nchars); /* copy cell up to dot */
- X }
- X
- X
- X
- Xinsert2(count) /* count is the number of chars added */
- X int count;
- X {
- X aa.p->b->f = insert_p; /* put the new cell where the old one was */
- X insert_p->b = aa.p->b;
- X insert_p = NULL;
- X
- X bb.p->f = aa.p; /* splice rest of buffer to end */
- X aa.p->b = bb.p;
- X movenchars(&aa, &bb, z-dot); /* squeeze buffer */
- X free_blist(bb.p->f); /* return unused cells */
- X bb.p->f = NULL; /* and end the buffer */
- X z += count; /* add # of chars inserted */
- X dot += count;
- X ctrl_s = -count; /* save string length */
- X }
- X
- X/* subroutine to delete n characters starting at dot */
- X/* argument is number of characters */
- X
- Xdelete1(nchars)
- X int nchars;
- X {
- X if (!nchars) return; /* 0 chars is a nop */
- X if (nchars < 0) /* delete negative number of characters? */
- X {
- X nchars = -nchars; /* make ll positive */
- X if (nchars > dot) ERROR(E_POP); /* don't delete beyond beg of buffer */
- X dot -= nchars; /* put pointer before deleted text */
- X }
- X else if (dot + nchars > z) ERROR(E_POP); /* don't delete beyond end of buffer */
- X
- X set_pointer(dot, &aa); /* pointer to beginning of area to delete */
- X set_pointer(dot+nchars, &bb); /* and to end */
- X if (dot < buff_mod) buff_mod = dot; /* update earliest char loc touched */
- X movenchars(&bb, &aa, z-(dot+nchars)); /* move text unless delete ends at z */
- X free_blist(aa.p->f); /* return any cells after end */
- X aa.p->f = NULL; /* end the buffer */
- X z -= nchars; /* adjust z */
- X }
- X
- X/* routine to process "O" command */
- X
- Xstruct qh obuff; /* tag string buffer */
- X
- Xdo_o()
- X {
- X int i, j; /* i used as start of tag, j as end */
- X int p, level; /* p is pointer to tag string, level is iteration lvl */
- X int epfound; /* flag for "second ! found" */
- X
- X if (!build_string(&obuff)) return; /* no tag spec'd: continue */
- X if (obuff.z > CELLSIZE) ERROR(E_STL); /* string too long */
- X esp->op = OP_START; /* consume any argument */
- X if (esp->flag1) /* is there one? */
- X {
- X esp->flag1 = 0; /* consume it */
- X if (esp->val1 < 0) return; /* computed goto out of range - */
- X for (i = 0; (i < obuff.z) && (esp->val1 > 0); i++) /* scan to find right tag */
- X if (obuff.f->ch[i] == ',') esp->val1--; /* count commas */
- X if (esp->val1 > 0) return; /* computed goto out of range + */
- X
- X/* now i is either at 0 or after the nth comma */
- X
- X for (j = i; j < obuff.z; j++) /* find end of tag */
- X if (obuff.f->ch[j] == ',') break; /* stop at next comma */
- X if (j == i) return; /* two adjacent commas: zero length tag */
- X }
- X
- X else
- X {
- X i = 0; /* not a computed goto: use whole tag buffer */
- X j = obuff.z;
- X }
- X
- X/* start from beginning of iteration or macro, and look for tag */
- X
- X if (cptr.flag & F_ITER) /* if in iteration */
- X {
- X cptr.p = cptr.il->p; /* restore */
- X cptr.c = cptr.il->c;
- X cptr.dot = cptr.il->dot;
- X }
- X else for (cptr.dot = cptr.c = 0; cptr.p->b->b != NULL; cptr.p = cptr.p->b); /* find macro start */
- X
- X/* search for tag */
- X
- X for (level = 0; ;) /* look through rest of command string */
- X {
- X switch (skipto(1)) /* look for interesting things, including ! */
- X {
- X case '<': /* start of iteration */
- X ++level;
- X break;
- X
- X case '>': /* end of iteration */
- X if ((level == 0) && (cptr.flag & F_ITER)) pop_iteration(1);
- X else --level;
- X break;
- X
- X case '!': /* start of tag */
- X for (epfound = 0; ; epfound = 0) /* keep looking for tag */
- X {
- X for (p = i; p < j; p++)
- X {
- X if (getcmdc(0) == '!') epfound = 1; /* mark "trailing ! found */
- X if (mapch_l[cmdc] != mapch_l[obuff.f->ch[p]]) break; /* compare */
- X }
- X if (p >= j) /* if all comparison chars matched */
- X {
- X if (getcmdc(0) == '!') return; /* and tag ends with !, found it */
- X }
- X else if (!epfound) while (getcmdc(0) != '!'); /* else look for next ! and continue */
- X }
- X break;
- X } /* end of switch */
- X } /* end of scan loop */
- X } /* end of subroutine */
- X
- X/* routine to skip to next ", ', |, <, or > */
- X/* skips over these chars embedded in text strings */
- X/* stops in ! if argument is nonzero */
- X/* returns character found, and leaves it in skipc */
- X
- Xchar skipto(arg)
- X int arg;
- X {
- X int atsw; /* "at" prefix */
- X char ta, term; /* temp attributes, terminator */
- X
- X for (atsw = 0; ;) /* forever */
- X {
- X while (!(ta = spec_chars[skipc = getcmdc(0)] & (A_X | A_S | A_T | A_Q))); /* read until something interesting found */
- X
- X again:
- X if (ta & A_Q) getcmdc(0); /* if command takes a Q spec, skip the spec */
- X if (ta & A_X) /* sought char found: quit */
- X {
- X if (skipc == '"') getcmdc(0); /* quote must skip next char */
- X return(skipc);
- X }
- X if (ta & A_S) /* other special char */
- X {
- X switch (skipc)
- X {
- X case '^': /* treat next char as CTL */
- X if (ta = spec_chars[skipc = getcmdc(0) & 0x1f]) goto again;
- X break;
- X
- X case '@': /* use alternative text terminator */
- X atsw = 1;
- X break;
- X
- X case CTL (^): /* ^^ is value of next char: skip that char */
- X getcmdc(0);
- X break;
- X
- X case CTL (A): /* type text */
- X term = (atsw) ? getcmdc(0) : CTL (A);
- X atsw = 0;
- X while (getcmdc(0) != term); /* skip text */
- X break;
- X
- X case '!': /* tag */
- X if (arg) return(skipc);
- X while (getcmdc(0) != '!'); /* skip until next ! */
- X break;
- X
- X case 'e': /* first char of two-letter E or F command */
- X case 'f':
- X if (spec_chars[getcmdc(0)] & ((skipc == 'e') ? A_E : A_F)) /* if one with a text arg */
- X {
- X term = (atsw) ? getcmdc(0) : ESC;
- X atsw = 0;
- X while (getcmdc(0) != term); /* read past terminator */
- X }
- X break;
- X } /* end "switch" */
- X } /* end "if (ta & A_S)" */
- X
- X else if (ta & A_T) /* command with a text argument */
- X {
- X term = (atsw) ? getcmdc(0) : ESC;
- X atsw = 0;
- X while (getcmdc(0) != term); /* skip text */
- X }
- X } /* end "forever" */
- X } /* end "skipto()" */
- X
- X/* find number of characters to next matching (, [, or { (like '%' in vi) */
- X
- Xdo_ctlp()
- X {
- X int i, l;
- X char c, c1;
- X
- X set_pointer(dot, &aa); /* point to text buffer */
- X switch(c1 = aa.p->ch[aa.c])
- X {
- X case '(':
- X c = ')'; /* match char is ) */
- X i = 1; /* direction is positive */
- X break;
- X
- X case ')':
- X c = '('; /* match char is ( */
- X i = -1; /* direction is negative */
- X break;
- X
- X case '[':
- X c = ']';
- X i = 1;
- X break;
- X
- X case ']':
- X c = '[';
- X i = -1;
- X break;
- X
- X case '{':
- X c = '}';
- X i = 1;
- X break;
- X
- X case '}':
- X c = '{';
- X i = -1;
- X break;
- X
- X case '<':
- X c = '>';
- X i = 1;
- X break;
- X
- X case '>':
- X c = '<';
- X i = -1;
- X break;
- X
- X case '"':
- X c = '\'';
- X i = 1;
- X break;
- X
- X case '\'':
- X c = '"';
- X i = -1;
- X break;
- X
- X default:
- X esp->val1 = i = 0; /* not on a matchable char, return 0 */
- X }
- X
- X l = 1; /* start with one unmatched char */
- X if (i > 0) /* if searching forward */
- X {
- X for (i = dot, fwdc(&aa); (i < z) && (l); fwdc(&aa) )
- X {
- X ++i;
- X if (aa.p->ch[aa.c] == c) --l;
- X else if (aa.p->ch[aa.c] == c1) ++l;
- X }
- X esp->val1 = (i < z) ? i - dot : 0;
- X }
- X else if (i < 0)
- X {
- X for (i = dot, backc(&aa); (i >= 0) && (l); backc(&aa) )
- X {
- X --i;
- X if (aa.p->ch[aa.c] == c) --l;
- X else if (aa.p->ch[aa.c] == c1) ++l;
- X }
- X esp->val1 = (i >= 0) ? i - dot : 0;
- X }
- X esp->flag1 = 1;
- X }
- X
- END_OF_te_subs.c
- if test 13995 -ne `wc -c <te_subs.c`; then
- echo shar: \"te_subs.c\" unpacked with wrong size!?
- fi
- # end of overwriting check
- fi
- echo shar: End of archive 2 \(of 4\).
- cp /dev/null ark2isdone
- DONE=true
- for I in 1 2 3 4 ; do
- if test ! -f ark${I}isdone ; then
- echo shar: You still need to run archive ${I}.
- DONE=false
- fi
- done
- if test "$DONE" = "true" ; then
- echo You have unpacked all 4 archives.
- echo "See the *.doc files"
- rm -f ark[1-9]isdone
- fi
- ## End of shell archive.
- exit 0
-